package br.edu.curso.java.dao;

import static br.edu.curso.java.dao.BaseDAO.getConexao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import br.edu.curso.java.VO.BaseVO;

public abstract class BaseDAOChaveUnica<t extends BaseVO, tchave> extends BaseDAO<t>  {

	public void excluir(tchave codigo) throws Exception{
		try {
			Connection conexao = getConexao();
			
			PreparedStatement pstm = conexao.prepareStatement(retornarComandoExcluir());
			
			pstm = this.carregarChavePrimaria(pstm,codigo);
			
			pstm.execute();
			pstm.close();
			conexao.close();
			
		} catch (Exception e) {
			e.printStackTrace();
                        throw e;
		}
    }
    
	private  String retornarComandoExcluir() {
    	
		StringBuilder comando = new StringBuilder();
    	
    	comando.append("delete from  ");
    	comando.append(this.getNomeTabela());
    	comando.append(" where ");
    	comando.append(this.getChavePrimaria());
   		comando.append("= ?;");

    	return comando.toString();
    }
	
	protected abstract PreparedStatement carregarChavePrimaria(PreparedStatement pstm, tchave codigo) ;
	
	
	public boolean existe(tchave codigo) throws Exception{
		boolean achou = false;
		try {
			Connection conexao = getConexao();
			
			PreparedStatement pstm = retornarComandoExiste(conexao, codigo);
			
			ResultSet rs = pstm.executeQuery();
			while (rs.next()) {
				achou = true;
			}
			pstm.close();
			conexao.close();
		} catch (Exception e) {
			e.printStackTrace();
                        throw e;
		}
		return achou;
	}
	
        public tchave retornarUltimaChave() {
                
                tchave chave = null;
                
		try {
			Connection conexao = getConexao();
			
			PreparedStatement pstm = retornarComandoUltimaChave(conexao);
			
			ResultSet rs = pstm.executeQuery();
                        
			while (rs.next()) {
                            
                            chave = carregarChave(rs);
			}
			pstm.close();
			conexao.close();
		} catch (Exception e) {
			e.printStackTrace();
                  }
                
		return chave;
	}
        
      	protected abstract tchave carregarChave(ResultSet rs);
        
        protected  PreparedStatement retornarComandoUltimaChave(Connection conexao)  {
		
		PreparedStatement pstm = null;
		
		try {
            		StringBuilder comando = new StringBuilder();
    	
                        comando.append("Select max( ");
                        comando.append(this.getChavePrimaria());
                        comando.append(" )from  ");
                        comando.append(this.getNomeTabela());
                        
			pstm = conexao.prepareStatement(comando.toString());

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return pstm;
		
	}
	protected  PreparedStatement retornarComandoExiste(Connection conexao, tchave codigo)  {
		
		PreparedStatement pstm = null;
		
		try {
			pstm = conexao.prepareStatement(retornarComandoExiste());

		pstm = this.carregarChavePrimaria(pstm,codigo);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return pstm;
		
	}

	private  String retornarComandoExiste() {
    	
		StringBuilder comando = new StringBuilder();
    	
    	comando.append("Select * from  ");
    	comando.append(this.getNomeTabela());
    	comando.append(" where ");
    	comando.append(this.getChavePrimaria());
   		comando.append("= ?;");

    	return comando.toString();
    }
	
	public t retornar(tchave codigo){
		t dep = null;
		
		try {
			Connection conexao = getConexao();
			PreparedStatement pstm = conexao.prepareStatement(retornarComandoRetornar());
			carregarChavePrimaria(pstm, codigo);
			ResultSet rs = pstm.executeQuery();
			while (rs.next()) {
				dep = carregarObjeto(rs);
			}
			
			pstm.close();
			conexao.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return dep;
	}
	
	private  String retornarComandoRetornar() {
    	
		StringBuilder comando = new StringBuilder();
    	
    	comando.append("Select * ");
    	comando.append(" from  ");
    	comando.append(this.getNomeTabela());
    	comando.append(" where ");
    	comando.append(this.getChavePrimaria());
   		comando.append("= ?;");

    	return comando.toString();
    }
}
